﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;

namespace 飞机大战.shader
{
    internal class DotShader
    {
        public class Shader : IDisposable
        {
            private int _handle;
            private int _uTotalTimeLocation;

            public Shader()
            {
                string vertSource = @"#version 330 core
                    layout (location = 0) in vec2 aPosition;
                    
                    void main()
                    {
                        gl_Position = vec4(aPosition, 0.0, 1.0);
                        gl_PointSize = 8.0;
                    }";

                string fragSource = @"#version 330 core
                    uniform float uTotalTime;
                    out vec4 FragColor;
                    
                    void main()
                    {
                        float cycleDuration = 2.0;
                        
                        float progress = mod(uTotalTime * 1e-9, cycleDuration) / cycleDuration;
                        
                        float brightness = 0.5 + 0.5 * sin(progress * 2.0 * 3.14159265359);
                        
                        FragColor = vec4(vec3(brightness), 1.0);
                    }";

                // 编译顶点着色器
                int vertexShader = GL.CreateShader(ShaderType.VertexShader);
                GL.ShaderSource(vertexShader, vertSource);
                GL.CompileShader(vertexShader);

                // 检查顶点着色器编译错误
                GL.GetShader(vertexShader, ShaderParameter.CompileStatus, out int vertSuccess);
                if (vertSuccess == 0)
                {
                    string infoLog = GL.GetShaderInfoLog(vertexShader);
                    throw new Exception($"顶点着色器编译错误:\n{infoLog}");
                }

                // 编译片段着色器
                int fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
                GL.ShaderSource(fragmentShader, fragSource);
                GL.CompileShader(fragmentShader);

                // 检查片段着色器编译错误
                GL.GetShader(fragmentShader, ShaderParameter.CompileStatus, out int fragSuccess);
                if (fragSuccess == 0)
                {
                    string infoLog = GL.GetShaderInfoLog(fragmentShader);
                    throw new Exception($"片段着色器编译错误:\n{infoLog}");
                }

                // 创建并链接程序
                _handle = GL.CreateProgram();
                GL.AttachShader(_handle, vertexShader);
                GL.AttachShader(_handle, fragmentShader);
                GL.LinkProgram(_handle);

                // 检查链接错误
                GL.GetProgram(_handle, GetProgramParameterName.LinkStatus, out int linkSuccess);
                if (linkSuccess == 0)
                {
                    string infoLog = GL.GetProgramInfoLog(_handle);
                    throw new Exception($"着色器程序链接错误:\n{infoLog}");
                }
            }

            public void Use() => GL.UseProgram(_handle);
            public void SetTotalTime(float totalTime) => GL.Uniform1(_uTotalTimeLocation, totalTime);
            public void Dispose() => GL.DeleteProgram(_handle);
        }
    }
}
